import {Fragment, type PropsWithoutRef, type ReactNode, Suspense, useEffect, useState} from "react";
import {Breadcrumb, Typography} from "antd";
import type {BreadcrumbItemType, BreadcrumbSeparatorType} from "antd/es/breadcrumb/Breadcrumb";
import {getArticle, type TArticle} from "../request/article.ts";
import {useParams} from "react-router";

function Loading() {
    return <span>内容正在加载中...</span>
}

export default function ArticleViewer() {
    const {articleId} = useParams();
    const [routePath, setRoutePath] = useState<Partial<BreadcrumbItemType & BreadcrumbSeparatorType>[]>([]);
    const [loading, setLoading] = useState<boolean>(true);
    const [article, setArticle] = useState<TArticle>();

    useEffect(function () {
        setRoutePath(new URL(location.href).pathname?.split("/").slice(0, -1).map(name => ({"title": name})));
        getArticle(parseInt(articleId as string)).then(res => {
            setArticle(res.data.body);
            setLoading(false);
        })
    }, [articleId])

    return <Fragment>
        <Breadcrumb items={routePath}/>
        <Suspense fallback={<Loading/>}>
            {
                loading ?
                    <Loading/>
                    :
                    (<Fragment>
                        <Typography.Title level={2}>{article?.title}</Typography.Title>
                        <ContentViewer content={article?.content}/>
                    </Fragment>)
            }
        </Suspense>
    </Fragment>
}


/**
 * Find the end symbol of current be scanned line
 * @param _symbol  what you would foud
 * @param paragraphs all paragraphs
 * @param startingPos where starting to find
 */
function findEndSymbol(_symbol: string, paragraphs: string[], startingPos: number) {
    let ans;
    /**
     find next position where {@code _symbol} occupancy
      */
    return (ans = paragraphs.slice(startingPos + 1).findIndex(p => p == _symbol)) == -1 ? startingPos : ans;
}

/**
 * Render paragraphs
 * @param paragraphs  _
 * @param editable every paragraph are editable or not
 */
function paragraphRender(paragraphs: string[], editable: boolean): ReactNode[] {
    const jsxElements: ReactNode[] = []
    for (let i = 0; i < paragraphs.length; i++) {
        let content = paragraphs[i]
        // find start with the flag of code
        // replace them and find next flag what the end
        // current line jump to the line where find the end symbol.
        if (paragraphs[i] === '```code') {
            content = content.replace('```code', '')
            const symbolIdx = findEndSymbol('```', paragraphs, i)
            const range = {
                start: i, end: symbolIdx
            }
            content = content + paragraphs.slice(range.start + 1, range.end + 1).join('\n');
            i = symbolIdx;
        }
        jsxElements.push(<Typography.Paragraph editable={editable}>{content}</Typography.Paragraph>)
    }

    return jsxElements;
}

/**
 * for view the article content
 */
function ContentViewer(props: PropsWithoutRef<{ content: string | undefined, editable?: boolean }>) {
    const content = props.content || ""
    const editable = props.editable ?? false // the default is not be edited
    const paragraphs = content.split('\n')
    const renderJsx: ReactNode[] = paragraphRender(paragraphs, editable)

    return <Fragment>
        {renderJsx}
    </Fragment>
}